package com.dragon.english_practice_back.handler;

import com.dragon.english_practice_back.reponse.Result;
import com.dragon.english_practice_back.reponse.ReturnCode;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.web.servlet.resource.NoResourceFoundException;

// 统一异常处理
@RestControllerAdvice
@ResponseBody
@Hidden
@Slf4j
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    /**
     * 处理404异常
     * @param ex NoHandlerFoundException
     * @return Result
     */
    @Override
    protected ResponseEntity<Object> handleNoResourceFoundException(
            NoResourceFoundException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {

        log.warn(ex.getMessage());

        return handleExceptionInternal(ex, new Result<>(ReturnCode.RC404.getCode(), ReturnCode.RC404.getMessage()), headers, status, request);
	}

    /**
     * 处理权限异常
     * @param ex AuthenticationException
     * @return Result
     */
    @ExceptionHandler(AccessDeniedException.class)
    public Result<?> handleAccessDeniedException(Exception ex) {
        return new Result<>(ReturnCode.RC403.getCode(), ReturnCode.RC403.getMessage());
    }

    /**
     *  处理身份验证异常
     * @param ex AuthenticationException
     * @return Result
     */

    @ExceptionHandler({ AuthenticationException.class })
    public Result<?> handleAuthenticationException(Exception ex) {
        log.warn(ex.getMessage());
        return  new Result<>(ReturnCode.RC401.getCode(), ReturnCode.RC401.getMessage());
    }

    /**
     * 处理未定义异常
     *
     * @param e otherException
     * @return Result
     */
    @ExceptionHandler(Exception.class)
    public Result<?> exception(Exception e) {
        log.error("未知异常 exception = {}", e.getMessage(), e);
        return new Result<>(ReturnCode.RC500.getCode(), ReturnCode.RC500.getMessage());
    }
}
